package arithmetic;

import java.util.Scanner;

/**
 * HJ39 判断两个IP是否属于同一子网
 * 知识点：
 * 1.ASCII码:0~9 / 48~57
 * 描述
 * IP地址是由4个0-255之间的整数构成的，用"."符号相连。
 * 二进制的IP地址格式有32位，例如：10000011，01101011，00000011，00011000;每八位用十进制表示就是131.107.3.24
 * 子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
 * 子网掩码与IP地址结构相同，是32位二进制数，由1和0组成，且1和0分别连续，其中网络号部分全为“1”和主机号部分全为“0”。
 * 你可以简单的认为子网掩码是一串连续的1和一串连续的0拼接而成的32位二进制数，左边部分都是1，右边部分都是0。
 * 利用子网掩码可以判断两台主机是否在同一子网中。
 * 若两台主机的IP地址分别与它们的子网掩码进行逻辑“与”运算（按位与/AND）后的结果相同，则说明这两台主机在同一子网中。
 *
 * 示例：
 * I P 地址　 192.168.0.1
 * 子网掩码　 255.255.255.0
 *
 * 转化为二进制进行运算：
 *
 * I P 地址　  11000000.10101000.00000000.00000001
 * 子网掩码　11111111.11111111.11111111.00000000
 *
 * AND运算   11000000.10101000.00000000.00000000
 *
 * 转化为十进制后为：
 * 192.168.0.0
 *
 *
 * I P 地址　 192.168.0.254
 * 子网掩码　 255.255.255.0
 *
 *
 * 转化为二进制进行运算：
 *
 * I P 地址　11000000.10101000.00000000.11111110
 * 子网掩码  11111111.11111111.11111111.00000000
 *
 * AND运算  11000000.10101000.00000000.00000000
 *
 * 转化为十进制后为：
 * 192.168.0.0
 *
 * 通过以上对两台计算机IP地址与子网掩码的AND运算后，我们可以看到它运算结果是一样的。均为192.168.0.0，所以这二台计算机可视为是同一子网络。
 *
 * 输入一个子网掩码以及两个ip地址，判断这两个ip地址是否是一个子网络。
 * 若IP地址或子网掩码格式非法则输出1，若IP1与IP2属于同一子网络输出0，若IP1与IP2不属于同一子网络输出2。
 *
 * 注:
 * 有效掩码与IP的性质为：
 * 1. 掩码与IP每一段在 0 - 255 之间
 * 2. 掩码的二进制字符串前缀为网络号，都由‘1’组成；后缀为主机号，都由'0'组成
 *
 * 输入描述：
 * 3行输入，第1行是输入子网掩码、第2，3行是输入两个ip地址
 * 题目的示例中给出了三组数据，但是在实际提交时，你的程序可以只处理一组数据（3行）。
 *
 * 输出描述：
 * 若IP地址或子网掩码格式非法则输出1，若IP1与IP2属于同一子网络输出0，若IP1与IP2不属于同一子网络输出2
 *
 * 示例1
 * 输入：
 * 255.255.255.0
 * 192.168.224.256
 * 192.168.10.4
 * 255.0.0.0
 * 193.194.202.15
 * 232.43.7.59
 * 255.255.255.0
 * 192.168.0.254
 * 192.168.0.1
 * 复制
 * 输出：
 * 1
 * 2
 * 0
 * 复制
 * 说明：
 * 对于第一个例子:
 * 255.255.255.0
 * 192.168.224.256
 * 192.168.10.4
 * 其中IP:192.168.224.256不合法，输出1
 *
 * 对于第二个例子:
 * 255.0.0.0
 * 193.194.202.15
 * 232.43.7.59
 * 2个与运算之后，不在同一个子网，输出2
 *
 * 对于第三个例子，2个与运算之后，如题目描述所示，在同一个子网，输出0
 */
public class TestHW39 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        // while (in.hasNextInt()) { // 注意 while 处理多个 case
        //     int a = in.nextInt();
        //     int b = in.nextInt();
        //     System.out.println(a + b);
        // }
        while (in.hasNextLine()) {
            String str1 = in.nextLine();
            String str2 = in.nextLine();
            String str3 = in.nextLine();
            // System.out.println(str1+"\n"+str2+"\n"+str3);
            boolean f = test(str1) && test(str2) && test(str3);
            str1  = demo1(str1);//子网掩码
            str2 = demo1(str2);
            str3 = demo1(str3);
            boolean f2 = test2(str1);
            if (!f || !f2) {
                System.out.println(1);
                continue;
            }

            // System.out.println(str1);
            int result =  testAnd(str1, str2, str3);
            System.out.println(result);
        }

        // String result = demo(255,"", 7);
        // System.out.println(result);
    }

    //IP地址与子网掩码的and运算
    public static int testAnd(String str1,String str2, String str3){
        String result1 = "";
        String result2 = "";
        int index = 0;
        int result = 0;
        while(index<str1.length()){
            if(str1.charAt(index) == 49 && str2.charAt(index) == 49){
                result1 += 1;
            }else{
                result1+= 0;
            }
            if(str1.charAt(index) == 49 && str3.charAt(index) == 49){
                result2 += 1;
            }else{
                result2+= 0;
            }
            index++;
        }
        // System.out.println(result1+"\n"+result2);
        if(result1.equals(result2)){
            result = 0;
        }else{
            result = 2;
        }
        return result;
    }

    //判断子网掩码是否符合：左边部分都是1，右边部分都是0
    public static boolean test2(String str){
        boolean f2 = true;
        int index = str.lastIndexOf('1');
        int index2 = str.indexOf('0');
        if(index2 == -1 || index2<index){
            f2 = false;
        }
        return f2;
    }
    //十进制转二进制
    public static String demo1(String str) {
        String str1 = "";
        String[] strs = str.split("\\.");
        int index = 0;
        while (index < strs.length) {
            int i = Integer.parseInt(strs[index]);
            str1 += demo(i, "", 7);
            index++;
        }
        return str1;
    }
    public static String demo(int num, String str, int index) {
        if (index < 0) {
            return str;
        }
        int num1 = (int)Math.pow(2, index);
        if (num1 > num) {
            str += "0";
        } else {
            str += "1";
            num -= num1;
        }
        index--;
        return demo(num, str, index);
    }
    //判断IP地址或者子网掩码的范围为0~255
    public static boolean test(String str) {
        boolean f = true;
        String[] strs = str.split("\\.");
        if (strs.length != 4) {
            f = false;
            return f;
        }
        int index = 0;
        while (index < strs.length) {
            try {
                int i = Integer.parseInt(strs[index]);
                if (i < 0 || i > 255) {
                    f = false;
                }
            } catch (Exception e) {
                f = false;
            }
            if (!f)break;
            index++;
        }
        return f;
    }
}
